using System;
using System.Collections;
using System.Data;
using System.IO;
using System.Security.Permissions;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Data.Common;


namespace Eve.Utility
{
    /// <summary>
    /// This calss is managing loading Market Orders from log file.
    /// It also exposing functionlaity to Save Orders in XML or DataBase.
    /// </summary>
    public class OrderList
    {
        private DataTable  _data = new DataTable();
        /// <summary>
        /// Default Contructor
        /// </summary>
        public OrderList() { }

        /// <summary>
        /// This method is used to Load Market Order log string
        /// </summary>
        /// <param name="orderFile">string containing market order log csv text</param>
        public void Load(string orderFile)
        {
            string[] matches =orderFile.Split('\n');
            
            for (int i = 0; i < matches.Length ; i++)
            {
                string line = matches[i];
                line=line.TrimEnd('\r');
                if (_data.Columns.Count == 0)
                {
                    LoadColumnLine(line, matches[i + 1], _data);
                }
                else
                {
                    LoadLine(line, _data);
                }
            }
            //_data.AcceptChanges();
            
        }

        public void LoadFile(string filename)
        {

            if (File.Exists(filename))
            {
                // Open the file to read from.
                using (StreamReader sr = File.OpenText(filename))
                {
                    Load(sr.ReadToEnd());
                }

            }
            else
            {
                throw new System.Exception("File not found, " + filename);
            }

            if (null == _data)
            {
                throw new InvalidOperationException("No data loaded from data source.");
            }

            
        }


        public List<Order> GetOrders()
        {
            List<Order> orderlist = new List<Order>();
            foreach (DataRow row in _data.Rows )
            {
                orderlist.Add(CreateOrder(row));

            }
            return orderlist;
        }

        public Order GetOrder(int i)
        {
            Order order = CreateOrder(_data.Rows[i]);
            return order;
        }

        public void Save(IDataAdapter dataAdapter)
        {
            DataSet ds = new DataSet();

            dataAdapter.Fill(ds);

            if (ds.Tables[0] != null)
            {
                foreach (DataRow row in _data.Rows  )
                {
                    DataRow[] foundrows=ds.Tables[0].Select("OrderID=" + row["OrderID"]);
                    if (foundrows.Length == 0)
                    {
                        DataRow newrow = ds.Tables[0].NewRow();
                        newrow["OrderID"]=row["OrderID"];
                        newrow["duration"] = row["duration"];
                        newrow["issued"] = row["duration"];
                        newrow["minVolume"] = row["duration"];
                        newrow["price"] = row["duration"];
                        newrow["range"] = row["duration"];
                        newrow["regionID"] = row["duration"];
                        newrow["volEntered"] = row["duration"];
                        newrow["volRemaining"] = row["duration"];
                        newrow["bid"] = row["bid"];
                        newrow["regionID"] = row["regionID"];
                        newrow["solarSystemID"] = row["solarSystemID"];
                        newrow["stationID"] = row["stationID"];
                        newrow["typeID"] = row["typeID"];
                        ds.Tables[0].Rows.Add(newrow);
                    }
                    else
                    {
                        foundrows[0]["duration"] = row["duration"];
                        foundrows[0]["issued"] = row["duration"];
                        foundrows[0]["minVolume"] = row["duration"];
                        foundrows[0]["price"] = row["duration"];
                        foundrows[0]["range"] = row["duration"];
                        foundrows[0]["volEntered"] = row["duration"];
                        foundrows[0]["volRemaining"] = row["duration"];
                    }
                }
            }
            dataAdapter.Update(ds);
        }

        public void SaveXML(string filename)
        {
            DataSet ds = new DataSet();

            ds.Tables.Add(_data);
            ds.WriteXml(filename);

        }

        public int Count
        {
            get { return _data.Rows.Count ; }
        }
        
        private Order CreateOrder(DataRow row)
        {
            Order order = new Order();
            order.bid = row["bid"].ToString();
            order.duration = (int)row["duration"];
            order.issued = row["issued"].ToString();
            order.minVolume = (int)row["minVolume"];
            order.orderID = (int)row["orderID"];
            order.price = (decimal)row["price"];
            order.range = (int)row["range"];
            order.regionID = (int)row["regionID"];
            order.solarSystemID = (int)row["solarSystemID"];
            order.stationID = (int)row["stationID"];
            order.typeID = (int)row["typeID"];
            order.volEntered = (int)row["volEntered"];
            order.volRemaining = (Decimal )row["volRemaining"];
            return order;
        }

        private void LoadLine(string line, DataTable data)
        {
            string[] dataValues;
            dataValues = line.Split(',');
            if (dataValues.Length == data.Columns.Count+1)
            {
                data.Rows.Add(CopyRowData(dataValues, data.NewRow()));
            }

        }

        private void LoadColumnLine(string columnLine, string dataLine, DataTable data)
        {
            // Parse the line
            string s = string.Empty ;
            string[] dataValues;
            string[] columnValues;
            DataColumn col;

            // Do the following to add schema.
            columnValues = columnLine.Split(',');
            dataValues = dataLine.Split(',');
            for (int k = 0; k < dataValues.Length;k++ )
            {
                if (!columnValues[k].Equals(""))
                {
                    col = new DataColumn(columnValues[k]);
                    try
                    {
                        int i = Convert.ToInt32(dataValues[k]);
                        col.DataType = typeof(Int32);
                    }
                    catch
                    {
                        try
                        {
                            Decimal i = Convert.ToDecimal(dataValues[k]);
                            col.DataType = typeof(Decimal);

                        }
                        catch
                        {
                            col.DataType = typeof(string);
                        }
                    }
                    finally
                    {
                        data.Columns.Add(col);
                    }
                }
            }
        }
        
        private DataRow CopyRowData(string[] source, DataRow target)
        {
            try
            {
                for (int i = 0; i < source.Length-1; i++)
                {
                    try
                    {

                        if (target.Table.Columns[i].DataType == typeof(string))
                        {
                            target[i] = source[i];
                        }
                        else if (target.Table.Columns[i].DataType == typeof(Int32))
                        {
                            target[i] = Convert.ToInt32(source[i]);
                        }
                        else if (target.Table.Columns[i].DataType == typeof(Decimal))
                        {
                            target[i] = Convert.ToDecimal(source[i]);

                        }
                        else if (target.Table.Columns[i].DataType == typeof(DateTime))
                        {
                            target[i] = Convert.ToDateTime(source[i]);

                        }
                    }
                    catch (Exception ex)
                    {
                        return target;
                    }
                    //we need to determine type
                }
            }
            catch (System.IndexOutOfRangeException)
            {
                return target;
            }
            return target;
        }
      
	

    }



}


